package com.uncp.comisiondeadmision.controlador;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UISelectOne;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.primefaces.event.FileUploadEvent;

import com.uncp.comisiondeadmision.service.ApplicationBusinessDelegate;
import com.uncp.comisiondeadmision.service.ISCarrera;
import com.uncp.comisiondeadmision.service.ISCdp;
import com.uncp.comisiondeadmision.service.ISEscuela;
import com.uncp.comisiondeadmision.service.ISFacultad;
import com.uncp.comisiondeadmision.service.ISHistorialIgv;
import com.uncp.comisiondeadmision.service.ISTipoModalidad;
import com.uncp.comisiondeadmision.util.entity.ECdp;
import com.uncp.comisiondeadmision.util.entity.EPostulante;
import com.uncp.comisiondeadmision.util.entity.ESolicitud;
import com.uncp.comisiondeadmision.util.entity.ETipomodalidad;
import com.uncp.comisiondeadmision.utils.Constantes;
import com.uncp.comisiondeadmision.utils.Util;

@ManagedBean(name = "cComprobanteDePago")
@SessionScoped
public class CComprobanteDePagoController extends CGenericController implements
		Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * Referencia del Entity correspondiente al CDP
	 */

	private ECdp eCdp;

	/**
	 * Referencia del Entity correspondiente a Tipo de Modalidad
	 */
	private ETipomodalidad eTipoModalidad;

	/**
	 * Contiene la Lista de Comprobantes de Pago
	 */
	private List<ECdp> lstECdp;

	/**
	 * Lista que contendra una coleccion de SelecItem(Variable para el el
	 * llenado de SelectedOneMenu) correspondiente a Tipo de Modalidad
	 */
	private List<SelectItem> lstTipoModalidad;

	/**
	 * Lista que contendra una coleccion de SelecItem(Variable para el el
	 * llenado de SelectedOneMenu) correspondiente a Facultad
	 */
	private List<SelectItem> lstFacultad;

	/**
	 * Lista que contendra una coleccion de SelecItem(Variable para el el
	 * llenado de SelectedOneMenu) correspondiente a Escuela
	 */
	private List<SelectItem> lstEscuela;

	/**
	 * Lista que contendra una coleccion de SelecItem(Variable para el el
	 * llenado de SelectedOneMenu) correspondiente a Carrera
	 */
	private List<SelectItem> lstCarrera;

	/**
	 * Contendra el elemento que se selecciona del SelectedOneMenu
	 * correspondiente al Tipo de Modalidad
	 */
	private UISelectOne codTipoModalidad;

	/**
	 * Contendra el elemento que se selecciona del SelectedOneMenu
	 * correspondiente a Facultad
	 */
	private UISelectOne codFacultad;

	/**
	 * Contendra el elemento que se selecciona del SelectedOneMenu
	 * correspondiente a Escuela
	 */
	private UISelectOne codEscuela;

	/**
	 * InputStream que contine la foto correspondiente a Postulante
	 */
	private InputStream inputStream;

	/**
	 * Referencia al estado GENERADO de Comprobante de Pago
	 */
	public static String ESTADO_GENERADO = "generado";

	/**
	 * Referencia del Concepto de Pago del CDP
	 */
	public static String CONCEPTO_CDP = "Por Concepto de Compra del Prospecto de la Modalidad :";

	private static ApplicationBusinessDelegate abd = new ApplicationBusinessDelegate();

	private ISCdp sCdp = abd.getIsCdp();

	private ISFacultad sFacultad = abd.getISFacultad();
	private ISEscuela sEscuela = abd.getISEscuela();
	private ISCarrera sCarrera = abd.getISCarrera();
	private ISTipoModalidad sTipoModalidad = abd.getISTipoModalidad();
	private ISHistorialIgv sHistorialIgv = abd.getISHistorialIgv();

	public CComprobanteDePagoController() {

		System.out
				.println("--- CComprobanteDePagoController - Inicializando CComprobanteDePago ---");

		eCdp = new ECdp();
		inputStream = null;
		eTipoModalidad = null;

		cargarTipoDeModalidades();
		cargarFacultades();
		generarComprobante();

	}

	@Override
	public String getInicializarControles() {

		eCdp = new ECdp();
		inputStream = null;
		eTipoModalidad = null;

		cargarTipoDeModalidades();
		cargarFacultades();
		generarComprobante();

		return "generacionCDP";
	}

	@Override
	public boolean antesDeGuardar() throws Exception {

		boolean verificar = true;

		// Tipo Modalidad
		if (!Util.esValorDiferenteDeSeleccione(eCdp.getPostulante()
				.getTipoModalidad().getInt_cod_moda()
				+ "")) {

			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necTipModalidadPostulante"), null);
			verificar = false;
		}
		// Nombre
		if (Util.estaVacio(eCdp.getPostulante().getStr_nom_postu())) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necNomPostulante"), null);
			verificar = false;
		} else {
			if (!Util.validaTextoNoNumerico(eCdp.getPostulante()
					.getStr_nom_postu())) {
				addFacesMessage(msg.SEVERITY_ERROR,
						obtenerProperty("necNoNumNomPostulante"), null);
				verificar = false;
			}
		}
		// Apellido Paterno
		if (Util.estaVacio(eCdp.getPostulante().getStr_apePat_postu())) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necApePatPostulante"), null);
			verificar = false;
		} else {
			if (!Util.validaTextoNoNumerico(eCdp.getPostulante()
					.getStr_apePat_postu())) {
				addFacesMessage(msg.SEVERITY_ERROR,
						obtenerProperty("necNoNumApePatPostulante"), null);
				verificar = false;
			}
		}
		// Apellido Materno
		if (Util.estaVacio(eCdp.getPostulante().getStr_apeMat_postu())) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necApeMatPostulante"), null);
			verificar = false;
		} else {
			if (!Util.validaTextoNoNumerico(eCdp.getPostulante()
					.getStr_apeMat_postu())) {
				addFacesMessage(msg.SEVERITY_ERROR,
						obtenerProperty("necNoNumApeMatPostulante"), null);
				verificar = false;
			}
		}

		// Fecha Nac
		if (Util.estaVacio(eCdp.getPostulante().getStr_fecNac_postu() + "")) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necFechNacPostulante"), null);
			verificar = false;
		}

		// DNI
		if (Util.estaVacio(eCdp.getPostulante().getStr_dni_postu())) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necDNIPostulante"), null);
			verificar = false;
		}
		// EMAIL
		if (Util.estaVacio(eCdp.getPostulante().getStr_email_postu())) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necEmailPostulante"), null);
			verificar = false;
		} else {
			if (!Util.validarCorreo(eCdp.getPostulante().getStr_email_postu())) {
				addFacesMessage(msg.SEVERITY_ERROR,
						obtenerProperty("necValEmailPostulante"), null);
				verificar = false;
			}
		}
		// Foto
		if (inputStream == null) {
			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("imgNecesario"), null);
			verificar = false;
		}
		// Carrera
		if (!Util.esValorDiferenteDeSeleccione(eCdp.getPostulante()
				.getCarrera().getInt_codcarrera()
				+ "")) {

			addFacesMessage(msg.SEVERITY_ERROR,
					obtenerProperty("necCarreraPostulante"), null);
			verificar = false;
		}

		return verificar;

	}

	@Override
	public void despuesDeGuardar() throws Exception {

		File file = new File(
				extContext.getRealPath(Constantes.UBICACIONDEDOCUMENTOS
						+ eCdp.getPostulante().getStr_urlFoto_postu()));

		FileOutputStream fileOutputStream = null;
		try {

			fileOutputStream = new FileOutputStream(file);

			int bulk;

			while (true) {
				bulk = inputStream.read();
				if (bulk < 0) {
					break;
				}
				fileOutputStream.write(bulk);
				fileOutputStream.flush();
			}

		} catch (FileNotFoundException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		} finally {

			fileOutputStream.close();

		}

		getInicializarControles();

	}

	public void listar() {

		System.out.println(eCdp.getStr_codcdp());

	}

	/**
	 * Metodo encargado de cargar los Tipos de Modalidad
	 */
	public void cargarTipoDeModalidades() {

		System.out.println("--- Cargando Tipos de Modalidades ---");

		lstTipoModalidad = new ArrayList<SelectItem>();

		lstTipoModalidad = sTipoModalidad.listarTipoDeModalidades();

	}

	/**
	 * Metodo encargado de cargar las Facultades
	 */
	public void cargarFacultades() {

		System.out.println("--- Cargando Facultades ---");

		lstFacultad = new ArrayList<SelectItem>();
		lstEscuela = new ArrayList<SelectItem>();
		lstCarrera = new ArrayList<SelectItem>();

		lstFacultad = sFacultad.listarFacultades();

	}

	/**
	 * Metodo encargado de cargar las Escuelas
	 * 
	 * @param e
	 *            Recibe el evento generado
	 */
	public void cargarEscuelas() {

		System.out.println("--- Cargando Escuelas ---");

		lstEscuela = new ArrayList<SelectItem>();
		lstCarrera = new ArrayList<SelectItem>();

		lstEscuela = sEscuela.listarEscuelas(Integer.parseInt(codFacultad
				.getValue().toString()));

	}

	/**
	 * Metodo encargado de cargar las Carreras
	 * 
	 * @param e
	 *            Recibe el evento generado
	 */
	public void cargarCarreras() {

		System.out.println("--- Cargando Carreras ---");

		lstCarrera = new ArrayList<SelectItem>();

		lstCarrera = sCarrera.listarCarreras(
				Integer.parseInt(codFacultad.getValue().toString()),
				Integer.parseInt(codEscuela.getValue().toString()));

	}

	/**
	 * Metodo Encargado de calcular el costo Total
	 */

	public void calcularCostoTotal(ValueChangeEvent e) {

		System.out.println("--- Calculando Costo Total ---");

		int codTipoModalidad = Integer.parseInt(e.getNewValue().toString());

		eTipoModalidad = sTipoModalidad
				.obtenerCostoXTipoModalidad(codTipoModalidad);

		eCdp.setHistorialIgv(sHistorialIgv.obtenerIgv());

		eCdp.getPostulante().getTipoModalidad()
				.setInt_cod_moda(codTipoModalidad);

		eCdp.setDbl_total(ECdp.calcularPago(eTipoModalidad.getDbl_cost_moda(),
				eCdp.getHistorialIgv().getDbl_valor()));

	}

	/**
	 * Metodo Encargado de volver la imagen a Bytes
	 * 
	 * @param event
	 *            Evento generado gracias al PrimeFaces contiene los datos
	 *            correspondientes a la imagen Seleccionada
	 */
	public void cargarFoto(FileUploadEvent event) {

		String extension = Util.obtenerTipoDeExtension(event.getFile()
				.getFileName());

		if (!Util.estaVacio(extension)) {

			eCdp.getPostulante().setStr_urlFoto_postu(
					eCdp.getStr_codcdp().concat(extension));

		}

		try {
			inputStream = event.getFile().getInputstream();

		} catch (IOException e) {

			e.printStackTrace();
		}

		addFacesMessage(msg.SEVERITY_INFO, obtenerProperty("imgCargCorrec"),
				null);

	}

	/**
	 * Metodo encargado de Grabar el Comprobante de Pago
	 * 
	 * @return Ubicacion
	 * @throws Exception
	 */
	

	public String generarComprobanteDePago() throws Exception {

		if (antesDeGuardar() == true) {

			// Fecha y Hora de emitido
			eCdp.setStr_fecha(new Date());

			// Concepto CDP

			eCdp.setStr_concepto(CONCEPTO_CDP + " "
					+ eTipoModalidad.getStr_nom_moda());

			// Estado Generado
			eCdp.setStr_estado(ESTADO_GENERADO);

			// Estado Postulante
			eCdp.getPostulante().setStr_estado_postu(EPostulante.estado(1));

			// guardar

			while (true) {

				try {

					sCdp.insertarCDP(eCdp);

					despuesDeGuardar();

					break;

				} catch (Exception e) {

					generarComprobante();

					String extension = Util.obtenerTipoDeExtension(eCdp
							.getPostulante().getStr_urlFoto_postu());

					if (!Util.estaVacio(extension)) {

						eCdp.getPostulante().setStr_urlFoto_postu(
								eCdp.getStr_codcdp().concat(extension));

					}

				}

			}

		}

		return null;

	}

	/**
	 * Metodo encargado de generar el codigo de CDP
	 */
	public void generarComprobante() {

		eCdp.setStr_codcdp(ECdp.aleatorio(99999999, 11111111));

	}

	public ECdp geteCdp() {
		return eCdp;
	}

	public void seteCdp(ECdp eCdp) {
		this.eCdp = eCdp;
	}

	public List<SelectItem> getLstFacultad() {
		return lstFacultad;
	}

	public void setLstFacultad(List<SelectItem> lstFacultad) {
		this.lstFacultad = lstFacultad;
	}

	public UISelectOne getCodTipoModalidad() {
		return codTipoModalidad;
	}

	public void setCodTipoModalidad(UISelectOne codTipoModalidad) {
		this.codTipoModalidad = codTipoModalidad;
	}

	public UISelectOne getCodFacultad() {
		return codFacultad;
	}

	public void setCodFacultad(UISelectOne codFacultad) {
		this.codFacultad = codFacultad;
	}

	public List<SelectItem> getLstEscuela() {
		return lstEscuela;
	}

	public void setLstEscuela(List<SelectItem> lstEscuela) {
		this.lstEscuela = lstEscuela;
	}

	public UISelectOne getCodEscuela() {
		return codEscuela;
	}

	public void setCodEscuela(UISelectOne codEscuela) {
		this.codEscuela = codEscuela;
	}

	public List<SelectItem> getLstCarrera() {
		return lstCarrera;
	}

	public void setLstCarrera(List<SelectItem> lstCarrera) {
		this.lstCarrera = lstCarrera;
	}

	public List<SelectItem> getLstTipoModalidad() {
		return lstTipoModalidad;
	}

	public void setLstTipoModalidad(List<SelectItem> lstTipoModalidad) {
		this.lstTipoModalidad = lstTipoModalidad;
	}

	public List<ECdp> getLstECdp() {
		try {
			lstECdp = sCdp.listarCDP();
		} catch (Exception e) {

			e.printStackTrace();
		}

		return lstECdp;
	}

	public void setLstECdp(List<ECdp> lstECdp) {
		this.lstECdp = lstECdp;
	}

}
